什么是原码、反码、补码?
什么是原码、反码、补码?
第一部分:计算机里的“数字”和“符号”——原码、反码、补码
我们都知道,我们平时用的数字是十进制的,有0到9这十个符号。但计算机可不是这样,它只会“开”和“关”,就像电灯一样。所以,计算机的世界里只有两个数字:0 和 1。
想象一下:
- 0 就是“关”或者“没有电”。
- 1 就是“开”或者“有电”。
计算机的所有信息,包括文字、图片、声音、数字,最后都要变成一串串的 0 和 1,才能被计算机理解和处理。
那么,怎么用 0 和 1 来表示我们熟悉的数字,特别是负数呢? 这就引出了“原码”、“反码”、“补码”这三种计算机里表示数字的方法。
我们先假设计算机用**8个“小格子”**来存一个数字,就像有8盏小灯泡,每个灯泡只能是亮或灭。
1.1 原码:最“老实”的表示方法
“原码”就像我们平时写数字一样,最直观。
-
表示正数:
-
第一个小格子(最左边那个)用来表示符号:如果是正数,它就是 0。
-
剩下的7个小格子就用来表示这个数字有多大。
-
例子:
数字
+5(正5)
- 符号位:
0(正数) - 数值
5用7个格子表示是000 0101(因为 22+20=4+1=5) - 所以,
+5的原码就是:0000 0101
- 符号位:
-
-
表示负数:
-
第一个小格子也用来表示符号:如果是负数,它就是 1。
-
剩下的7个小格子同样表示这个数字有多大(是它的“绝对值”)。
-
例子:
数字
-5(负5)
- 符号位:
1(负数) - 数值
5还是000 0101 - 所以,
-5的原码就是:1000 0101
- 符号位:
-
原码的缺点:
- “零”有两种表示:
+0是0000 0000,而-0却是1000 0000。两个不同的表示都代表“零”,这会让计算机很困惑,处理起来很麻烦。 - 加减法复杂: 如果要用原码直接做加减法,计算机需要先判断是正数还是负数,哪个大哪个小,然后再决定是相加还是相减。这就像我们人工算账一样,比较复杂。
1.2 反码:稍微“聪明”一点的表示方法
“反码”是为了解决原码加减法复杂的问题,迈出了一小步。
-
表示正数:
- 反码和原码一模一样。 (正数总是最简单,不用变)
- 例子:
+5的反码:0000 0101(和原码一样)
-
表示负数:
-
从这个负数的原码开始,符号位不变(还是
1)。 -
剩下的7个数值位,全部“取反”:0 变成 1,1 变成 0。
-
例子:
−5的反码
- 先看
-5的原码:1000 0101 - 符号位
1不变。 - 数值位
000 0101全部取反,变成111 1010。 - 所以,
-5的反码就是:1111 1010
- 先看
-
反码的缺点:
- 虽然加法运算变得稍微简单了,但**“零”仍然有两种表示:**
+0的反码:0000 0000-0的反码:1111 1111(因为-0原码是1000 0000,符号位不变,数值位000 0000取反就是111 1111)。- 这还是会给计算机带来麻烦。
1.3 补码:计算机里最“实用”的表示方法
“补码”就是为了彻底解决“零”的两种表示和加减法复杂的问题,它是计算机里最主流、最常用的表示方法。
-
表示正数:
- 补码和原码、反码一模一样。 (正数还是那么老实,没变)
- 例子:
+5的补码:0000 0101
-
表示负数:
-
从这个负数的反码开始,末位(最右边那位)加 1。
-
例子:
-5的补码
- 先看
-5的反码:1111 1010 - 末位加 1:
1111 1010 + 1 = 1111 1011 - 所以,
-5的补码就是:1111 1011
- 先看
-
补码的优点:
-
“零”的表示是唯一的: 无论是
+0还是-0,它们的补码最终都变成了0000 0000。这样计算机就不用担心有两个零了。 -
加减法统一:
最大的优点!有了补码,计算机做加减法就变得非常简单和统一了。比如,计算
A - B,计算机可以直接把它看成
A + (-B 的补码)。所有的减法都变成了加法,大大简化了计算机的内部电路。
-
例子:
5 + (-5)(在计算机里就是
+5的补码 加上
-5的补码)
-
+5的补码:0000 0101 -
-5的补码:1111 1011 -
两者相加:
0000 0101 (+5) + 1111 1011 (-5) ----------- 1 0000 0000 (最左边的1溢出,8位只能存后面8位) -
结果就是
0000 0000,正好是0的补码,完美!
-
-
总结一下原码、反码、补码的关系(正数都一样,负数按顺序变):
| 数字 | 8位原码 | 8位反码 | 8位补码 |
|---|---|---|---|
| +5 | 0000 0101 | 0000 0101 | 0000 0101 |
| -5 | 1000 0101 | 1111 1010 | 1111 1011 |
第二部分:数字的“翻译官”——进制之间的转换
我们平时用的是十进制,但计算机用的是二进制。为了方便人类查看和理解,还会用到八进制和十六进制。它们就像不同的语言,需要有“翻译官”来互相转换。
什么是“进制”?
“进制”就是计算数字时“逢几进一”的规则。
- 十进制 (Decimal): 逢十进一,用 0-9 十个符号。
- 二进制 (Binary): 逢二进一,只用 0 和 1 两个符号。
- 八进制 (Octal): 逢八进一,用 0-7 八个符号。
- 十六进制 (Hexadecimal): 逢十六进一,用 0-9 和 A-F (A代表10, B代表11, … F代表15) 十六个符号。
2.1 其他进制(二、八、十六)转十进制:用“位值”相加
这个方法很简单,就像我们理解十进制数字一样:一个数字的每一位都有一个“位置价值”(位权)。
方法: 把每个位置上的数字,乘以它对应的“位置价值”,然后全部加起来。
“位置价值”怎么算?就是“进制数”的“位数次方”。
例子:
-
把二进制数
1011翻译成十进制:-
1011就像是:
- 最右边的
1对应 20 (就是 1) - 它左边的
1对应 21 (就是 2) - 再左边的
0对应 22 (就是 4) - 最左边的
1对应 23 (就是 8)
- 最右边的
-
所以:
1*8 + 0*4 + 1*2 + 1*1 = 8 + 0 + 2 + 1 = 11 -
二进制的
1011就等于十进制的11。
-
-
把八进制数
375翻译成十进制:-
375就像是:
- 最右边的
5对应 80 (就是 1) - 中间的
7对应 81 (就是 8) - 最左边的
3对应 82 (就是 64)
- 最右边的
-
所以:
3*64 + 7*8 + 5*1 = 192 + 56 + 5 = 253 -
八进制的
375就等于十进制的253。
-
-
把十六进制数
AF翻译成十进制:-
AF就像是:
F(代表 15) 对应 160 (就是 1)A(代表 10) 对应 161 (就是 16)
-
所以:
10*16 + 15*1 = 160 + 15 = 175 -
十六进制的
AF就等于十进制的175。
-
2.2 十进制转其他进制:用“除法”和“余数”
这个方法就像是把一个大蛋糕(十进制数)分给不同进制的小朋友,看能分多少次,每次剩下多少。
方法: “除以基数取余数,倒着读余数”。
- 用你要转换成的进制的基数(比如转二进制就用2,转八进制就用8,转十六进制就用16)去连续除以十进制整数。
- 每次得到的余数记录下来。
- 一直除到商为0为止。
- 最后,把所有的余数从下往上(倒序)排列起来,就是转换后的结果。
例子:
- 把十进制数
11翻译成二进制:- 11 ÷ 2 = 5 余
1 - 5 ÷ 2 = 2 余
1 - 2 ÷ 2 = 1 余
0 - 1 ÷ 2 = 0 余
1 - 倒着读余数:
1011 - 所以十进制的
11就等于二进制的1011。
- 11 ÷ 2 = 5 余
- 把十进制数
253翻译成八进制:- 253 ÷ 8 = 31 余
5 - 31 ÷ 8 = 3 余
7 - 3 ÷ 8 = 0 余
3 - 倒着读余数:
375 - 所以十进制的
253就等于八进制的375。
- 253 ÷ 8 = 31 余
2.3 二进制与八进制/十六进制的“快速”翻译(因为是“亲戚”)
二进制、八进制、十六进制之间有一种特殊的“亲戚关系”,因为 8 是 23,16 是 24。这让它们之间的转换变得非常快,就像直接查字典一样。
记住一个对应关系:
- 3 位二进制 = 1 位八进制
- 4 位二进制 = 1 位十六进制
方法:
-
二进制转八进制:
-
把二进制数字从右往左(或小数点开始)每三位分成一组。
-
如果最左边不够三位,就在前面补 0。
-
然后,把每一组三位二进制数分别翻译成一个八进制数字。
-
例子:
把二进制
1011011转八进制
- 分组:
1011011 - 补零:
001011011 - 翻译:
001是1,011是3,011是3 - 所以
1011011(二进制) =133(八进制)
- 分组:
-
-
八进制转二进制:
-
把每个八进制数字,都翻译成三位二进制数。
-
例子:
把八进制
133转二进制
1是0013是0113是011- 合起来:
001011011(最前面的0可以省略) =1011011(二进制)
-
-
二进制转十六进制:
-
把二进制数字从右往左(或小数点开始)每四位分成一组。
-
如果最左边不够四位,就在前面补 0。
-
然后,把每一组四位二进制数分别翻译成一个十六进制数字。
-
例子:
把二进制
101101101转十六进制
- 分组:
101101101 - 补零:
000101101101 - 翻译:
0001是1,0110是6,1101是D(代表13) - 所以
101101101(二进制) =16D(十六进制)
- 分组:
-
-
十六进制转二进制:
-
把每个十六进制数字,都翻译成四位二进制数。
-
例子:
把十六进制
16D转二进制
1是00016是0110D(13) 是1101- 合起来:
000101101101(最前面的0可以省略) =101101101(二进制)
-
8421 法:二进制和十进制的“速查表”
“8421 法”是专门用来快速地在4位二进制数和十进制数之间进行转换的方法。它基于二进制数的“位值”概念,也就是我们之前说的“位置价值”。
请看这张“魔术卡片”:
| 位值 (权力值) | 8 | 4 | 2 | 1 |
|---|---|---|---|---|
| 二进制数字 | (位) | (位) | (位) | (位) |
它的意思就是:
- 最右边的小格子(第1位)如果亮了 (是1),它代表的值就是 1。
- 往左边数第二个小格子(第2位)如果亮了 (是1),它代表的值就是 2。
- 往左边数第三个小格子(第3位)如果亮了 (是1),它代表的值就是 4。
- 最左边的小格子(第4位)如果亮了 (是1),它代表的值就是 8。
如果一个小格子灭了 (是0),那它就不代表任何值。
2.1 二进制转十进制 (用8421法):看亮灯,加数字
方法:
- 把一个4位二进制数,套到“8421”这四个位值下面。
- 哪个位上的灯是“1”(亮了),就把对应的位值加起来。
- 哪个位上的灯是“0”(灭了),就不用加。
例子:
-
二进制
0101(4位) 转十进制:位值: 8 4 2 1 数字: 0 1 0 10在 8 的位置 (灭了,不加 8)1在 4 的位置 (亮了,加 4)0在 2 的位置 (灭了,不加 2)1在 1 的位置 (亮了,加 1)- 所以,。 (是不是很快?)
-
二进制
1100(4位) 转十进制:位值: 8 4 2 1 数字: 1 1 0 01在 8 的位置 (亮了,加 8)1在 4 的位置 (亮了,加 4)0在 2 的位置 (灭了,不加 2)0在 1 的位置 (灭了,不加 1)- 所以,。
-
二进制
0000到1111的全部对应:0000 -> 0 0001 -> 1 0010 -> 2 0011 -> 3 (2+1) 0100 -> 4 0101 -> 5 (4+1) 0110 -> 6 (4+2) 0111 -> 7 (4+2+1) 1000 -> 8 1001 -> 9 (8+1) 1010 -> 10 (8+2) 1011 -> 11 (8+2+1) 1100 -> 12 (8+4) 1101 -> 13 (8+4+1) 1110 -> 14 (8+4+2) 1111 -> 15 (8+4+2+1)
2.2 十进制转二进制 (用8421法):凑数字,开电灯
方法:
- 拿到一个十进制数(只能是 0 到 15 之间的),看看它能由 8、4、2、1 哪些数字组合而成。
- 如果用到了某个位值,那个位置的二进制就是“1”(灯亮)。
- 如果没用到,那个位置的二进制就是“0”(灯灭)。
例子:
-
十进制
7转二进制:- 7 = 4 + 2 + 1
- 所以,4、2、1 的位置亮灯,8 的位置灭灯。
- 结果是:
0111。
-
十进制
13转二进制:- 13 = 8 + 4 + 1
- 所以,8、4、1 的位置亮灯,2 的位置灭灯。
- 结果是:
1101。
8421 法和八进制/十六进制的“亲戚关系”
8421 法不仅仅能帮我们翻译4位二进制和十进制,它也是二进制和八进制/十六进制快速转换的基础!
我们再来看看这个图:
| 十六进制 | 二进制(4位) | 八进制(3位) |
|---|---|---|
| 0 | 0000 | 000 |
| 1 | 0001 | 001 |
| 2 | 0010 | 010 |
| 3 | 0011 | 011 |
| 4 | 0100 | 100 |
| 5 | 0101 | 101 |
| 6 | 0110 | 110 |
| 7 | 0111 | 111 |
| 8 | 1000 | (无对应) |
| 9 | 1001 | (无对应) |
| A (10) | 1010 | (无对应) |
| B (11) | 1011 | (无对应) |
| C (12) | 1100 | (无对应) |
| D (13) | 1101 | (无对应) |
| E (14) | 1110 | (无对应) |
| F (15) | 1111 | (无对应) |
你看,每一位十六进制数,直接就对应了四位二进制数(正好是 8421 法能表示的范围)。每一位八进制数,直接就对应了三位二进制数(8421 法的前三位,或者说 421 法)。
所以,当你需要转换:
-
二进制到十六进制:
- 从右边开始,把二进制数每四位分成一组。
- 每组用 8421 法快速翻译成一个十六进制数字。
- 例子:
1101011010110(二进制)- 分组:
110101101011010 - 补零:
0110101101011010 - 翻译:
6B5A - 所以,
- 分组:
-
十六进制到二进制:
- 把每个十六进制数字,直接用 8421 法翻译成四位二进制数。
- 例子:
F3A(十六进制)F(15) ->11113->0011A(10) ->1010- 合起来:
111100111010(二进制)
总结:
8421 法就像一个方便的小工具,让你在 0-15 范围内的十进制数和 4 位二进制数之间快速切换。而这种“按固定位数分组”的思维,正是二进制、八进制和十六进制之间快速转换的秘密。